import {ScannerResult} from "../../types";
import path from "path";
import fs from "fs-extra";
import folderSize from "../../utils/folderSize";
import {FormatUtil} from "../../utils/FormatUtil";

// 依赖信息
export interface Dependency {
  name: string;
  version: string;
  type: 'dependencies' | 'devDependencies' | 'peerDependencies';
}

/**
 * 从依赖对象中提取依赖信息
 */
function extractDependencies(
  dependencies: Record<string, string>,
  type: 'dependencies' | 'devDependencies' | 'peerDependencies'
): Dependency[] {
  return Object.entries(dependencies).map(([name, version]) => ({
    name,
    version,
    type
  }));
}

export async function NpmScanner(projectPath: string): Promise<ScannerResult | null> {
  try {
    const packageJsonPath = path.join(projectPath, 'package.json');

    if (!await fs.pathExists(packageJsonPath)) {
      return null;
    }

    const packageJson = await fs.readJSON(packageJsonPath);

    const noModulesSize = await folderSize.loose(projectPath, {
      ignore: /^node_modules/
    })
    const nodeModulesSize = await folderSize.loose(path.join(projectPath, 'node_modules'));
    const totalSize = noModulesSize + nodeModulesSize;

    // 提取依赖信息
    const dependencies = extractDependencies(packageJson.dependencies || {}, 'dependencies');
    const devDependencies = extractDependencies(packageJson.devDependencies || {}, 'devDependencies');
    const peerDependencies = extractDependencies(packageJson.peerDependencies || {}, 'peerDependencies');

    return {
      projectName: packageJson.name || path.basename(projectPath),
      basicInfo: [
        {"名称": packageJson.name || path.basename(projectPath)},
        {"类型": "npm"},
        {"路径": projectPath},
        {"大小": FormatUtil.formatFileSize(totalSize)},
        {"node_modules 大小": FormatUtil.formatFileSize(nodeModulesSize)},
        {"描述": packageJson.description},
        {
          "作者": typeof packageJson.author === 'string'
            ? packageJson.author
            : packageJson.author?.name
        },
        {"版本": packageJson.author?.version},
        {"依赖": dependencies.length},
        {"开发依赖": devDependencies.length},
        {"peer 依赖": peerDependencies.length},
      ],
      mores: [
        {
          title: "脚本",
          type: "table",
          list: Object.entries(packageJson.scripts || {}).map(([name, script]) => ({
            name,
            script
          }))
        },
        {
          title: "依赖",
          type: "table",
          list: dependencies
        },
        {
          title: "开发依赖",
          type: "table",
          list: devDependencies
        },
        {
          title: "peer依赖",
          type: "table",
          list: peerDependencies
        }
      ]
    };
  } catch (error) {
    console.error(`扫描 NPM 项目失败: ${projectPath}`, error);
    return null;
  }
}
